<template>
  <div class="background-management">
    <div class="page-header">
      <h2>背景资源管理</h2>
      <div class="header-actions">
        <el-button
            type="danger"
            :disabled="selectedItems.length === 0"
            @click="handleBatchDelete"
        >
          <el-icon><Delete /></el-icon> 批量删除
        </el-button>
      </div>
    </div>

    <!-- 搜索和筛选 -->
    <div class="filter-toolbar">
      <div class="search-filter">
        <el-select
            v-model="fileTypeFilter"
            placeholder="文件类型"
            clearable
            @change="handleFilterChange"
            class="filter-select"
        >
          <el-option label="全部" value="" />
          <el-option label="图片" value="image" />
          <el-option label="视频" value="video" />
        </el-select>
      </div>

      <!-- 上传按钮 -->
      <el-dropdown @command="handleUploadCommand" trigger="click">
        <el-button type="primary">
          <el-icon><Upload /></el-icon> 上传资源
          <el-icon class="el-icon--right"><ArrowDown /></el-icon>
        </el-button>
        <template #dropdown>
          <el-dropdown-menu>
            <el-dropdown-item command="image">上传图片</el-dropdown-item>
            <el-dropdown-item command="video">上传视频</el-dropdown-item>
          </el-dropdown-menu>
        </template>
      </el-dropdown>

      <!-- 隐藏的上传组件 -->
      <el-upload
          ref="uploadRef"
          class="hidden-upload"
          :action="getUploadUrl()"
          :headers="{ 'Authorization': 'Bearer ' + getToken() }"
          :on-success="handleUploadSuccess"
          :on-error="handleUploadError"
          :before-upload="beforeUpload"
          :show-file-list="false"
          :data="{ fileType: currentFileType }"
          :accept="currentFileType === 'image' ? 'image/jpeg,image/png' : 'video/mp4,video/webm'"
          style="display: none;"
      >
        <div></div>
      </el-upload>
    </div>

    <!-- 资源列表 -->
    <div v-loading="backgroundStore.loading" class="gallery-content">
      <!-- 全选按钮 -->
      <div class="select-all-bar">
        <el-checkbox
            v-model="isAllSelected"
            @change="handleSelectAll"
            :indeterminate="isIndeterminate"
        >
          全选
        </el-checkbox>
        <span class="selection-info" v-if="selectedItems.length > 0">
          已选择 {{ selectedItems.length }} 项
        </span>
      </div>

      <el-empty v-if="backgrounds.length === 0" description="暂无背景资源" />
      <div v-else class="background-grid">
        <div
            v-for="bg in backgrounds"
            :key="bg.id"
            :class="['background-item', { 'is-selected': isSelected(bg.id) }]"
            @click="toggleSelectItem(bg)"
        >
          <!-- 选择复选框 -->
          <div class="item-checkbox" @click.stop="toggleSelectItem(bg)">
            <el-checkbox
                v-model="bg.selected"
                @change="() => handleItemCheckboxChange(bg)"
            ></el-checkbox>
          </div>

          <div class="background-preview">
            <el-image
                v-if="bg.fileType === 'image'"
                :src="bg.url"
                fit="cover"
                class="preview-media"
                loading="lazy"
            >
              <template #error>
                <div class="image-error">
                  <el-icon><Picture /></el-icon>
                </div>
              </template>
            </el-image>
            <video
                v-else
                :src="bg.url"
                class="preview-media"
                preload="metadata"
                muted
                loop
                @mouseover="playVideo($event)"
                @mouseout="pauseVideo($event)"
            ></video>
            <div class="background-actions">
              <el-button
                  type="primary"
                  size="small"
                  circle
                  @click.stop="handlePreview(bg)"
              >
                <el-icon><View /></el-icon>
              </el-button>
              <el-button
                  type="danger"
                  size="small"
                  circle
                  @click.stop="handleDeleteBackground(bg)"
              >
                <el-icon><Delete /></el-icon>
              </el-button>
            </div>
          </div>
          <div class="background-info">
            <div class="background-name">{{ bg.name || formatFilename(bg.url) }}</div>
            <div class="background-meta">
              <el-tag size="small" :type="bg.fileType === 'image' ? 'success' : 'warning'">
                {{ bg.fileType === 'image' ? '图片' : '视频' }}
              </el-tag>
              <span class="background-date">{{ formatDate(bg.createTime) }}</span>
            </div>
          </div>
        </div>
      </div>
    </div>

    <!-- 分页 -->
    <div class="gallery-pagination">
      <el-pagination
          v-model:current-page="currentPage"
          v-model:page-size="pageSize"
          :page-sizes="[12, 24, 36, 48]"
          layout="sizes, prev, pager, next, total"
          :total="backgroundStore.total"
          @size-change="handleSizeChange"
          @current-change="handlePageChange"
      />
    </div>

    <!-- 删除确认对话框 -->
    <el-dialog
        v-model="deleteDialog.visible"
        :title="deleteDialog.isBatch ? '批量删除背景' : '删除背景'"
        width="400px"
        :close-on-click-modal="false"
    >
      <div class="delete-confirm">
        <template v-if="deleteDialog.isBatch">
          <p>确定要删除选中的 {{ selectedItems.length }} 项背景资源吗？此操作不可恢复。</p>
        </template>
        <template v-else>
          <p>确定要删除此背景吗？此操作不可恢复。</p>
        </template>
      </div>
      <template #footer>
        <div class="dialog-footer">
          <el-button @click="deleteDialog.visible = false">取消</el-button>
          <el-button
              type="danger"
              @click="confirmDelete"
              :loading="deleteDialog.loading"
          >
            确定删除
          </el-button>
        </div>
      </template>
    </el-dialog>

    <!-- 预览对话框 -->
    <el-dialog
        v-model="previewDialog.visible"
        :title="previewDialog.title"
        width="800px"
        :close-on-click-modal="true"
    >
      <div class="preview-container">
        <el-image
            v-if="previewDialog.type === 'image'"
            :src="previewDialog.url"
            fit="contain"
            class="preview-image"
        />
        <video
            v-else
            :src="previewDialog.url"
            class="preview-video"
            controls
            autoplay
        ></video>
      </div>
    </el-dialog>
  </div>
</template>

<script setup>
import { ref, onMounted, computed, watch } from 'vue'
import { Search, Upload, Picture, View, Delete, ArrowDown } from '@element-plus/icons-vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { getToken } from '@/utils/auth'
import { getUploadUrl } from '@/utils/uploadConfig.js'
import { useBackgroundStore } from '@/stores/video/background'

// 状态
const backgroundStore = useBackgroundStore()
const searchKeyword = ref('')
const fileTypeFilter = ref('')
const currentFileType = ref('image')
const currentPage = ref(1)
const pageSize = ref(24)
const selectedItems = ref([])

const uploadRef = ref(null);

// 背景列表
const backgrounds = computed(() => {
  return backgroundStore.backgrounds.map(bg => ({
    ...bg,
    selected: selectedItems.value.includes(bg.id)
  }));
});

// 全选状态
const isAllSelected = computed(() => {
  return backgrounds.value.length > 0 && backgrounds.value.every(bg => bg.selected);
});

const isIndeterminate = computed(() => {
  return selectedItems.value.length > 0 && !isAllSelected.value;
});

// 删除对话框状态
const deleteDialog = ref({
  visible: false,
  loading: false,
  background: null,
  isBatch: false
});

// 预览对话框状态
const previewDialog = ref({
  visible: false,
  type: 'image',
  url: '',
  title: '资源预览'
});

// 初始化
onMounted(() => {
  fetchBackgrounds();
});

// 获取背景资源列表
const fetchBackgrounds = async () => {
  await backgroundStore.getBackgrounds({
    page: currentPage.value,
    pageSize: pageSize.value,
    type: fileTypeFilter.value,
    keyword: searchKeyword.value
  });

  // 重置选择
  selectedItems.value = [];
};

// 搜索处理
const handleSearch = () => {
  currentPage.value = 1;
  fetchBackgrounds();
};

// 筛选处理
const handleFilterChange = () => {
  currentPage.value = 1;
  fetchBackgrounds();
};

// 分页处理
const handleSizeChange = (size) => {
  pageSize.value = size;
  fetchBackgrounds();
};

const handlePageChange = (page) => {
  currentPage.value = page;
  fetchBackgrounds();
};

// 选择上传文件类型
const handleUploadCommand = (command) => {
  currentFileType.value = command;

  // 延时一小段时间确保文件类型已更新
  setTimeout(() => {
    // 手动触发文件选择
    const uploadElement = uploadRef.value.$el.querySelector('input[type="file"]');
    if (uploadElement) {
      uploadElement.click();
    }
  }, 100);
};

// 上传前验证
const beforeUpload = (file) => {
  const isImage = currentFileType.value === 'image';
  const isVideo = currentFileType.value === 'video';

  // 检查文件类型
  if (isImage) {
    const isJPG = file.type === 'image/jpeg';
    const isPNG = file.type === 'image/png';
    if (!isJPG && !isPNG) {
      ElMessage.error('图片只能是 JPG 或 PNG 格式!');
      return false;
    }
  } else if (isVideo) {
    const isMP4 = file.type === 'video/mp4';
    const isWebM = file.type === 'video/webm';
    if (!isMP4 && !isWebM) {
      ElMessage.error('视频只能是 MP4 或 WebM 格式!');
      return false;
    }
  }

  // 检查文件大小
  const maxSize = 50 * 1024 * 1024; // 50MB
  if (file.size > maxSize) {
    ElMessage.error('文件大小不能超过 50MB!');
    return false;
  }

  ElMessage.info('开始上传，请稍候...');
  return true;
};

// 上传成功处理
const handleUploadSuccess = (response) => {
  if (response.code === 200 && response.data) {
    ElMessage.success('上传成功');
    fetchBackgrounds(); // 刷新列表
  } else {
    ElMessage.error(response.message || '上传失败');
  }
};

// 上传失败处理
const handleUploadError = (error) => {
  console.error('上传失败:', error);
  ElMessage.error('上传失败，请稍后重试');
};

// 预览
const handlePreview = (background) => {
  previewDialog.value = {
    visible: true,
    type: background.fileType,
    url: background.url,
    title: background.name || formatFilename(background.url)
  };
};

// 删除背景
const handleDeleteBackground = (background) => {
  deleteDialog.value = {
    visible: true,
    loading: false,
    background: background,
    isBatch: false
  };
};

// 批量删除背景
const handleBatchDelete = () => {
  if (selectedItems.value.length === 0) return;

  deleteDialog.value = {
    visible: true,
    loading: false,
    background: null,
    isBatch: true
  };
};

// 确认删除
const confirmDelete = async () => {
  deleteDialog.value.loading = true;

  try {
    if (deleteDialog.value.isBatch) {
      // 批量删除
      const results = await Promise.all(
          selectedItems.value.map(id => backgroundStore.removeBackground(id))
      );

      const successCount = results.filter(res => res.code === 200).length;

      if (successCount > 0) {
        ElMessage.success(`成功删除 ${successCount} 项资源`);
        if (successCount < selectedItems.value.length) {
          ElMessage.warning(`有 ${selectedItems.value.length - successCount} 项资源删除失败`);
        }

        // 刷新列表
        fetchBackgrounds();
      } else {
        ElMessage.error('批量删除失败');
      }
    } else {
      // 单个删除
      const response = await backgroundStore.removeBackground(deleteDialog.value.background.id);

      if (response.code === 200) {
        ElMessage.success('删除成功');
        // 列表已在 store 内更新，无需手动刷新

        // 从选中列表中移除
        const index = selectedItems.value.indexOf(deleteDialog.value.background.id);
        if (index !== -1) {
          selectedItems.value.splice(index, 1);
        }
      } else {
        ElMessage.error(response.message || '删除失败');
      }
    }
  } catch (error) {
    console.error('删除背景失败:', error);
    ElMessage.error('删除失败，请稍后重试');
  } finally {
    deleteDialog.value.loading = false;
    deleteDialog.value.visible = false;
  }
};

// 选择管理
const isSelected = (id) => {
  return selectedItems.value.includes(id);
};

const toggleSelectItem = (background) => {
  const id = background.id;
  const index = selectedItems.value.indexOf(id);

  if (index === -1) {
    selectedItems.value.push(id);
  } else {
    selectedItems.value.splice(index, 1);
  }

  // 更新背景的选择状态
  background.selected = !background.selected;
};

const handleItemCheckboxChange = (background) => {
  toggleSelectItem(background);
};

const handleSelectAll = (value) => {
  if (value) {
    // 全选
    selectedItems.value = backgrounds.value.map(bg => bg.id);
    backgrounds.value.forEach(bg => {
      bg.selected = true;
    });
  } else {
    // 取消全选
    selectedItems.value = [];
    backgrounds.value.forEach(bg => {
      bg.selected = false;
    });
  }
};

// 视频预览控制
const playVideo = (event) => {
  const video = event.target;
  if (video.paused) {
    video.play().catch(err => console.error('视频播放失败:', err));
  }
};

const pauseVideo = (event) => {
  const video = event.target;
  if (!video.paused) {
    video.pause();
  }
};

// 格式化日期
const formatDate = (dateString) => {
  if (!dateString) return '';

  const date = new Date(dateString);
  return date.toLocaleDateString('zh-CN', {
    year: 'numeric',
    month: '2-digit',
    day: '2-digit'
  });
};

// 从URL提取文件名
const formatFilename = (url) => {
  if (!url) return '未命名';

  try {
    const urlObj = new URL(url);
    const pathParts = urlObj.pathname.split('/');
    const filename = pathParts[pathParts.length - 1];

    // 如果有文件名，截取前20个字符显示
    if (filename) {
      return filename.length > 20 ? filename.substring(0, 20) + '...' : filename;
    }

    return '未命名';
  } catch (error) {
    return '未命名';
  }
};
</script>

<style scoped>
.hidden-upload {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
}

.background-management {
  padding: 20px;
}

.page-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 24px;
}

.page-header h2 {
  font-size: 22px;
  font-weight: 600;
  margin: 0;
}

.header-actions {
  display: flex;
  gap: 12px;
}

.filter-toolbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 24px;
  gap: 10px;
}

.search-filter {
  display: flex;
  gap: 10px;
  flex: 1;
}

.search-input {
  flex: 1;
  max-width: 300px;
}

.filter-select {
  width: 120px;
}

.select-all-bar {
  display: flex;
  align-items: center;
  margin-bottom: 16px;
}

.selection-info {
  margin-left: 12px;
  font-size: 14px;
  color: #606266;
}

.gallery-content {
  flex: 1;
  margin-bottom: 20px;
  min-height: 500px;
}

.background-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 24px;
}

.background-item {
  position: relative;
  border-radius: 8px;
  overflow: hidden;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
  transition: transform 0.3s ease, box-shadow 0.3s ease;
  cursor: pointer;
  background-color: #f5f7fa;
}

.background-item:hover {
  transform: translateY(-5px);
  box-shadow: 0 5px 15px rgba(0, 0, 0, 0.2);
}

.background-item.is-selected {
  border: 2px solid #409eff;
  transform: translateY(-5px);
  box-shadow: 0 5px 15px rgba(64, 158, 255, 0.3);
}

.item-checkbox {
  position: absolute;
  top: 10px;
  left: 10px;
  z-index: 10;
  padding: 4px;
  background-color: rgba(255, 255, 255, 0.8);
  border-radius: 4px;
}

.background-preview {
  position: relative;
  height: 160px;
  overflow: hidden;
}

.preview-media {
  width: 100%;
  height: 100%;
  object-fit: cover;
  background-color: #ebeef5;
}

.background-actions {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 10px;
  background-color: rgba(0, 0, 0, 0.5);
  opacity: 0;
  transition: opacity 0.3s ease;
}

.background-item:hover .background-actions {
  opacity: 1;
}

.background-info {
  padding: 12px;
}

.background-name {
  font-size: 14px;
  font-weight: 500;
  color: #303133;
  margin-bottom: 6px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.background-meta {
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 12px;
  color: #909399;
}

.background-date {
  font-size: 12px;
}

.image-error {
  display: flex;
  justify-content: center;
  align-items: center;
  width: 100%;
  height: 100%;
  background-color: #f5f7fa;
  color: #909399;
  font-size: 20px;
}

.gallery-pagination {
  display: flex;
  justify-content: center;
  margin-top: 32px;
}

.delete-confirm {
  text-align: center;
  padding: 10px 0;
}

.dialog-footer {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
}

.preview-container {
  width: 100%;
  display: flex;
  justify-content: center;
}

.preview-image {
  max-width: 100%;
  max-height: 70vh;
}

.preview-video {
  width: 100%;
  max-height: 70vh;
}
</style>